package it.gtd.swimpool.controller.resources;

import it.gtd.swimpool.model.business.AdministrationManager;
import it.gtd.swimpool.model.business.UserManager;
import it.gtd.swimpool.model.entity.User;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
import java.util.List;

@Stateless
@Path("/")
public class SessionResource extends SecuredResource {
    private static class Credentials {
        private String email, password;

        public String getEmail() {
            return email;
        }

        public void setEmail(String email) {
            this.email = email;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public String getRole() {
            return null;
        }

        public void setRole() {

        }

        public Credentials() { }

        public Credentials(String email, String password) {
            this.setEmail(email);
            this.setPassword(password);
        }
    }

    @PersistenceContext
    private EntityManager entityManager;

    @EJB
    private UserManager userManager;

    @EJB
    private AdministrationManager administrationManager;

    @GET
    @Path("/logout")
    public Response logout(@CookieParam(Cookie.SESSION_ID) String sessionId) {
        checkUser(sessionId).logout();
        return Response.ok()
                       .header("Set-Cookie", Cookie.SESSION_ID + "=")
                       .build();
    }

    @POST
    @Path("/login")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces("text/plain; charset=UTF-8")
    public Response login(
        Credentials credentials
    ) throws URISyntaxException, UnsupportedEncodingException {
        User user = entityManager.createNamedQuery("User.byEmail", User.class).
                setParameter("email", credentials.getEmail()).getSingleResult();

        if (user.verifyPassword(credentials.getPassword())) {
            String sessionId = user.login();
            return Response.ok(sessionId)
                           .header("Set-Cookie", Cookie.SESSION_ID + "=" + sessionId)
                           .build();
        }

        return Response.status(Response.Status.UNAUTHORIZED).build();
    }

    @POST
    @Path("/users")
    @Consumes(MediaType.APPLICATION_JSON)
    public void register(
        Credentials credentials
    ) {
        userManager.register(credentials.getEmail(), credentials.getPassword());
    }

    @PUT
    @Path("/accounts/{id}")
    public void activateAccount(
        @CookieParam(Cookie.SESSION_ID) String sessionId,
        @PathParam("id") int id
    ) {
        checkSuperUser(sessionId);

        User target = entityManager.find(User.class, id);

        administrationManager.forceActivate(target);
    }

    @GET
    @Path("/accounts/inactive")
    public List<User> getInactiveAccounts(
        @CookieParam(Cookie.SESSION_ID) String sessionId
    ) {
        checkSuperUser(sessionId);
        return entityManager.createNamedQuery("User.inactive", User.class).getResultList();
    }

    @GET
    @Path("/activate/{hash}")
    @Produces(MediaType.TEXT_PLAIN)
    public String activateAccount(
        @PathParam("hash") String activationHash
    ) throws UnsupportedEncodingException {
        User user = userManager.activate(activationHash);
        return "Account for " + user.getEmail() + " activated!";
    }
}
